

#include <swarm.h>
#include <swarmio.h>

#include <stdlib.h>
#include <string.h>

sw_id _sw_next_ins_id = 0;

void sw_print_insect(sw_insect *ins){

  printf("ID: %d loc: ", ins->id);
  sw_print_vec(&ins->loc);
  printf(" vel: ");
  sw_println_vec(&ins->vel);

}

sw_insect *sw_new_insect(){

  sw_insect *ins = (sw_insect *)malloc(sizeof(sw_insect));

  memset(ins, 0, sizeof(sw_insect));
  ins->id = _sw_next_ins_id++;
  pthread_mutex_init(&ins->lock, NULL);

  return ins;

}

int _swio_desc_add_force(sw_force ***flist, sw_size_t *len, sw_force *f){

  sw_force **new_flist = (sw_force **)
    malloc(sizeof(sw_force *) * (*len + 1));
  if (new_flist == NULL){
    printf("Panick no mem.\n");
    return 1;
  }
  memcpy(new_flist, *flist, *len * sizeof(sw_force *));

  new_flist[(*len)++] = f;

  if (*flist) free(*flist);
  *flist = new_flist;

  return 0;

}

int swio_desc_add_rforce(swio_insect_desc *ins, char *f_name, sw_swarm *sw){

  /* First find the force in the swarm's force list. */
  int offset = sw_find_force_offset(sw, f_name);
  if (offset == -1) // error
    return 1;

  sw_force *f = sw->forces + offset;

  return _swio_desc_add_force(&ins->frespond, &ins->f_len_r, f);

}

int swio_desc_add_eforce(swio_insect_desc *ins, char *f_name, sw_swarm *sw){

  /* First find the force in the swarm's force list. */
  int offset = sw_find_force_offset(sw, f_name);
  if (offset == -1) // error
    return 1;

  sw_force *f = sw->forces + offset;

  return _swio_desc_add_force(&ins->femit, &ins->f_len_e, f);

}

/**
 * Turns the description of the insects into actual insects in the swarm
 * data structure.
 */
void swio_desc_to_insects(swio_insect_desc *desc, sw_swarm *sw){

  //printf("[swarmio] Quantity: %d\n", desc->quantity);

  /* Make the insects color. */
  GdkColor col;
  gboolean ok = gdk_color_parse(desc->color, &col);

  if (ok != TRUE){
    printf("[swarmio] Invalid color requested: %s, using white instead.\n",
	   desc->color);
    gdk_color_parse("white", &col);
  }

  /* Now start spawning off some insects. */
  if (desc->quantity < 1) return;

  int i = 0;
  for ( ; i < desc->quantity; i++){

    sw_insect *ins = sw_new_insect();

    ins->type = desc->type;
    ins->f_len_r = desc->f_len_r;
    ins->f_len_e = desc->f_len_e;
    ins->frespond = desc->frespond;
    ins->femit = desc->femit;
    ins->color = col;

    if (desc->quantity == 1){
      ins->vel = desc->vel;
      ins->loc = desc->loc;
    } else {
      memset(&ins->vel, 0, sizeof(sw_xmm_vec));
      ins->loc.x = sw_random();
      ins->loc.y = sw_random();
    }

    sw_add_insect(sw, ins);

  }


}
